---
id: lab7-intro
slug: /labs/lab7
sidebar_position: 1
---

# 7. Обработка символьных строк

Алиас: `шифрование`.

## Цель работы

При выполнении лабораторной работы освоить следующие приемы программирования:

- работу с символьными строками;
- работу с файлами.

## Задание

Провести кодирование и декодирование текста (массива символов) при помощи кода Цезаря с переменным сдвигом по таблице ASCII-кодов. Величина сдвига для каждой позиции в исходном тексте - сумма (по модулю `128`) кодов символов слова кодового блокнота, стоящего в блокноте на той же позиции. Если кодовый блокнот имеет слов меньше, чем количество символов в исходном тексте, то по исчерпании слов в нём перейти к первому слову и продолжить.

:::info

На основе кодового блокнота целесообразно сначала сформировать по заданному правилу целочисленный массив ключей, который затем использовать при кодировании. Эти действия оформить в виде отдельной функции.

:::

Исследовать повторяемость символов в закодированном тексте (сколько каких кодов одного и того же исходного символа получено) в зависимости от кодового блокнота и длины исходного текста. Результаты исследования представить в виде таблицы (продумать формат таблицы самостоятельно). Обязательные колонки таблицы выглядят следующим образом:

- `символ` - рассматриваемый символ из исходного текста;
- `кол-во в исх-ом` - сколько раз встречается рассматриваемый символ в исходном тексте;
- `кол-во в вар-ов` - сколько вариантов использовалось, чтобы закодировать рассматриваемый символ;
- `размер блокнота` - размер кодового блокнота (слов в кодовом блокноте);
- `длина исх-ый` - длина исходного текста.

Статистические данные хранить в массиве `stat[128]`, элементами которого являются структурами. Вид структуры определяется исполнителем.

В таблице отобразить `5` неповторяющихся символов, выбранных случайным образом.

:::info
Для большей достоверности статистических результатов в качестве исходного текста и кодового блокнота использовать текстовые файлы размером около `1` Кбайта.
:::

:::caution
Обратите внимание, что размер файлов может быть больше `1` Кбайта. Поэтому рекомендуется обработку файла с ключом осуществлять построчно, как это показано в [примере](Examples/WorkingWithStrings.md).
:::

Текстовые документы, которые используются в программе:

- `source.txt` - исходный текст (текст должен содержать только символы из таблицы ASCII), расположен рядом с исполняемой программой;
- `key.txt` - кодовой блокнот (текст содержит только ASCII символы), расположен рядом с исполняемой программой;
- `encoded.txt` - закодированный текст, создается при выполнении программы в директории c исполняемой программой;
- `decoded.txt` - расшифрованный текст из `encoded.txt`, создается при выполнении программы в директории c исполняемой программой.

Все файлы необходимо выводить в консоль. Вывод файла в консоль оформить в виде отдельной функции.

:::info
Для удобства код, отвечающий за кодирование и декодирование текста, расположить в `caesar.c` (или в `caesar.cpp`). Не забывайте про заголовочный файл `caesar.h`.
:::

### Примечание к заданию

Для студентов кафедры ИУ5 раньше предлагалось использовать таблицу, содержащую расширенные символы ASCII, а именно Win-1251 (кириллица). Поэтому мощность алфавита задавалась числом `256`, вместо `128`.

В современных приложениях отдается предпочтение Юникоду (UTF-8) (подробнее [здесь](https://ru.wikipedia.org/wiki/Windows-1251)).

## Пример вывода в консоли

:::info
Обратите внимание, что это только пример. Конечный вид вывода в консоль, в том числе и формат таблицы, определяется исполнителем.
:::

```bash
Содержимое source.txt:
Let's start a new life from the darkness
Until the light reveals the end
Sinister faces, growing curses
This is my last war

Содержимое key.txt:
The only memory left is trauma
Imaginary friend's kind words
The evening train was shaking
I purified the imperfect flowers
The pain in my heart getting higher
My comedy show at its peak
The frogs were crying on our way home
This is my last war

Содержимое encoded.txt:
Rkz'y yzgxz g tkc rolk lxus znk jgxqtkyy Atzor znk romnz xkbkgry znk ktj Yotoyzkx lgiky, mxucotm iaxyky Znoy oy se rgyz cgx

Содержимое decoded.txt:
Let's start a new life from the darkness
Until the light reveals the end
Sinister faces, growing curses
This is my last war

Исследование зависимости символов в закодированном тексте от кодового блокнота и длины исходного текста:
| символ | кол-во в исх-ом | кол-во в вар-ов | размер блокнота | длина исх-ый | 
|--------|-----------------|-----------------|-----------------|--------------|
|      x |               0 |               0 |               0 |            0 |
|      y |               0 |               0 |               0 |            0 |
|      z |               0 |               0 |               0 |            0 |
|      f |               0 |               0 |               0 |            0 |
|      g |               0 |               0 |               0 |            0 |
```

## Указания по выполнению работы

### Шифр Цезаря

:::info

Подробнее о Шифре цезаря см. в статьях ["Цезаря"](https://ru.wikipedia.org/wiki/Шифр_Цезаря) и ["Шифр Цезаря или как просто зашифровать текст"](https://habr.com/ru/post/534058/)

:::

Цезарь для шифрования своих посланий использовал следующий прием. При кодировании и декодировании писем он заменял буквы в письме на следующие по алфавиту буквы с постоянным смещением, равным `13`, то есть к порядковому номеру буквы в латинском алфавите, содержащим `26` букв, он прибавлял `13` и получал порядковый номер буквы в кодируемом (декодируемом) письме. Если полученный таким образом номер буквы был больше `26`, то он уменьшался на `26`.

## Решение возможных проблем

### CMake собрал программу без ошибок, но тест не проходит из-за ошибки `'utf-8' codec can't decode byte`

> UTF-8 — это кодировка символов переменной длины, что, в данном случае, означает длину от 1 до 4 байт на символ. Первый байт UTF-8 используется для кодирования ASCII, что означает, что данный набор символов полностью обратно совместим с ASCII. UTF-8 означает, что символы ASCII и Latin полностью взаимозаменяемы с небольшим увеличением размера данных, так как используется только первый байт. Подробнее [здесь](https://wiki.gentoo.org/wiki/UTF-8/ru).

Тестирующая программа записывает консольный вывод кодирующей программы и пытается привести его к кодировке UTF-8. Вот пример ошибки, которая может возникнуть при столкновенни с кодом символа, не входящий в таблицу ASCII:

```bash
utf-8' codec can't decode byte 0xb6 in position 2177: invalid start byte
```

В этом примере тестирующая программа пытается интепретировать консольный вывод в форрмате UTF-8. Во время интерпретации тестирующая программа наткнулась на символ `0xB6`, который из расширенной символьной таблицы [ASCII Win-1251](https://snipp.ru/handbk/table-ascii) кириллица. Таким образом, кодирующая программа ошибочно записывает этот символ в файл `encoded.txt`. Убедитесь, что преобразование символов происходит корректно.

## Проверка задания

Подготовленная программа для решения задания проверяется вручную преподавателем (визуальный контроль).

## Методический материал

1. [Требования к отчету](RequirementsForReport.md)
2. Примеры программ:
   1. [Пример программы работы с символьными строками](Examples/WorkingWithStrings.md)
3. Полезная информация:
   1. [О вводе-выводе и работе с файлами в C](UsefulInformation/StreamsAndFIlesC.md)
   2. [О потоках ввода-вывода и работе с файлами в C++](UsefulInformation/StreamsAndFIlesCpp.md)
4. Контрольные вопросы:
   1. [Для потока на С](TestQuestion/ForC.md)
   2. [Для потока на С++](TestQuestion/ForCpp.md)
